# 工作流模板管理器
import json
import logging
from typing import Dict, List, Optional, Tuple
from django.contrib.auth.models import User
from django.utils import timezone
from django.db import transaction
from django.core.exceptions import ValidationError
from datetime import datetime, timedelta

from .models_workflow import WorkflowTemplate, WorkflowInstance, WorkflowStepTask
from .workflow_engine import WorkflowEngine

logger = logging.getLogger(__name__)


class WorkflowTemplateManager:
    """工作流模板管理器"""
    
    def __init__(self):
        self.workflow_engine = WorkflowEngine()
    
    def create_template_from_instance(self, instance_id: int, template_name: str, created_by: User) -> WorkflowTemplate:
        """从工作流实例创建模板"""
        
        try:
            instance = WorkflowInstance.objects.get(id=instance_id)
            
            # 分析实例的执行路径，生成优化的模板
            optimized_definition = self._analyze_and_optimize_workflow(instance)
            
            template = WorkflowTemplate.objects.create(
                name=template_name,
                template_type=instance.template.template_type,
                description=f"基于实例 '{instance.instance_name}' 创建的优化模板",
                workflow_definition=optimized_definition,
                created_by=created_by,
                is_optimized=True
            )
            
            logger.info(f"从实例 {instance_id} 创建模板 {template.id}")
            return template
            
        except Exception as e:
            logger.error(f"从实例创建模板失败: {e}")
            raise
    
    def _analyze_and_optimize_workflow(self, instance: WorkflowInstance) -> Dict:
        """分析并优化工作流定义"""
        
        original_def = instance.template.workflow_definition
        tasks = instance.step_tasks.all().order_by('created_at')
        
        # 分析实际执行路径
        executed_steps = []
        step_performance = {}
        
        for task in tasks:
            if task.status == 'completed':
                executed_steps.append(task.step_id)
                
                # 计算步骤执行时间
                if task.started_at and task.completed_at:
                    duration = (task.completed_at - task.started_at).total_seconds()
                    step_performance[task.step_id] = duration
        
        # 优化工作流定义
        optimized_def = original_def.copy()
        
        # 移除未执行的步骤
        original_steps = optimized_def.get('steps', [])
        optimized_steps = []
        
        for step in original_steps:
            step_id = step.get('id')
            if step_id in executed_steps:
                # 保留执行过的步骤
                optimized_step = step.copy()
                
                # 添加性能数据
                if step_id in step_performance:
                    optimized_step['avg_duration'] = step_performance[step_id]
                
                optimized_steps.append(optimized_step)
        
        optimized_def['steps'] = optimized_steps
        optimized_def['optimization_info'] = {
            'source_instance_id': instance.id,
            'optimized_at': timezone.now().isoformat(),
            'removed_steps': len(original_steps) - len(optimized_steps),
            'performance_data': step_performance
        }
        
        return optimized_def
    
    def validate_template_compatibility(self, template_id: int, target_object_type: str) -> Dict:
        """验证模板与目标对象类型的兼容性"""
        
        try:
            template = WorkflowTemplate.objects.get(id=template_id)
            
            compatibility_result = {
                'compatible': True,
                'warnings': [],
                'errors': []
            }
            
            # 检查模板类型匹配
            if template.template_type != target_object_type:
                compatibility_result['warnings'].append(
                    f"模板类型 '{template.template_type}' 与目标类型 '{target_object_type}' 不匹配"
                )
            
            # 检查步骤配置
            workflow_def = template.workflow_definition
            steps = workflow_def.get('steps', [])
            
            for step in steps:
                step_id = step.get('id')
                
                # 检查分配人配置
                assignee_config = step.get('assignee', {})
                if assignee_config.get('type') == 'dynamic':
                    expression = assignee_config.get('expression', '')
                    if not self._validate_dynamic_expression(expression, target_object_type):
                        compatibility_result['warnings'].append(
                            f"步骤 '{step_id}' 的动态分配表达式可能不适用于目标类型"
                        )
                
                # 检查条件配置
                if step.get('type') == 'condition':
                    condition = step.get('condition', {})
                    if not self._validate_condition_fields(condition, target_object_type):
                        compatibility_result['warnings'].append(
                            f"步骤 '{step_id}' 的条件字段可能不适用于目标类型"
                        )
            
            if compatibility_result['warnings'] or compatibility_result['errors']:
                compatibility_result['compatible'] = len(compatibility_result['errors']) == 0
            
            return compatibility_result
            
        except Exception as e:
            logger.error(f"验证模板兼容性失败: {e}")
            return {
                'compatible': False,
                'errors': [f'验证失败: {str(e)}']
            }
    
    def _validate_dynamic_expression(self, expression: str, object_type: str) -> bool:
        """验证动态表达式"""
        
        # 简单的表达式验证
        if expression.startswith('workflow_data.'):
            field_name = expression[14:]
            
            # 根据对象类型检查字段是否存在
            if object_type == 'asset':
                valid_fields = ['department_id', 'category_id', 'manager_id', 'owner_id']
                return field_name in valid_fields
        
        return True  # 默认认为有效
    
    def _validate_condition_fields(self, condition: Dict, object_type: str) -> bool:
        """验证条件字段"""
        
        field = condition.get('field')
        if not field:
            return True
        
        # 根据对象类型检查字段
        if object_type == 'asset':
            valid_fields = ['status', 'value', 'department_id', 'category_id']
            return field in valid_fields
        
        return True
    
    def batch_create_instances(self, template_id: int, instance_configs: List[Dict], created_by: User) -> Dict:
        """批量创建工作流实例"""
        
        try:
            template = WorkflowTemplate.objects.get(id=template_id, is_active=True)
            
            results = {
                'success_count': 0,
                'failed_count': 0,
                'errors': [],
                'created_instances': []
            }
            
            with transaction.atomic():
                for i, config in enumerate(instance_configs):
                    try:
                        instance = self.workflow_engine.create_workflow_instance(
                            template_id=template_id,
                            instance_name=config.get('instance_name', f'批量实例 {i+1}'),
                            related_object_type=config.get('related_object_type'),
                            related_object_id=config.get('related_object_id'),
                            created_by=created_by,
                            initial_data=config.get('initial_data', {})
                        )
                        
                        # 如果配置了自动启动
                        if config.get('auto_start', False):
                            self.workflow_engine.start_workflow(instance.id, created_by)
                        
                        results['created_instances'].append({
                            'instance_id': instance.id,
                            'instance_name': instance.instance_name,
                            'status': 'success'
                        })
                        results['success_count'] += 1
                        
                    except Exception as e:
                        error_msg = f"创建实例 {i+1} 失败: {str(e)}"
                        results['errors'].append(error_msg)
                        results['failed_count'] += 1
                        logger.error(error_msg)
            
            return results
            
        except Exception as e:
            logger.error(f"批量创建实例失败: {e}")
            raise
    
    def analyze_template_usage(self, template_id: int, days: int = 30) -> Dict:
        """分析模板使用情况"""
        
        try:
            template = WorkflowTemplate.objects.get(id=template_id)
            
            # 计算时间范围
            end_date = timezone.now()
            start_date = end_date - timedelta(days=days)
            
            instances = WorkflowInstance.objects.filter(
                template=template,
                created_at__range=[start_date, end_date]
            )
            
            # 基础统计
            total_instances = instances.count()
            status_distribution = {}
            
            for status_choice in WorkflowInstance.INSTANCE_STATUS_CHOICES:
                status_code = status_choice[0]
                count = instances.filter(status=status_code).count()
                status_distribution[status_code] = {
                    'count': count,
                    'percentage': (count / total_instances * 100) if total_instances > 0 else 0
                }
            
            # 性能分析
            completed_instances = instances.filter(
                status='completed',
                started_at__isnull=False,
                completed_at__isnull=False
            )
            
            performance_stats = {}
            if completed_instances.exists():
                durations = [
                    (instance.completed_at - instance.started_at).total_seconds()
                    for instance in completed_instances
                ]
                
                performance_stats = {
                    'avg_duration': sum(durations) / len(durations),
                    'min_duration': min(durations),
                    'max_duration': max(durations),
                    'completion_rate': completed_instances.count() / total_instances * 100
                }
            
            # 步骤分析
            step_stats = self._analyze_template_steps(template, instances)
            
            # 用户使用分析
            user_stats = instances.values('created_by__username').annotate(
                count=Count('id')
            ).order_by('-count')
            
            return {
                'template_info': {
                    'id': template.id,
                    'name': template.name,
                    'type': template.template_type,
                    'created_at': template.created_at,
                    'version': template.version
                },
                'usage_stats': {
                    'total_instances': total_instances,
                    'status_distribution': status_distribution,
                    'analysis_period': f'{days} 天'
                },
                'performance_stats': performance_stats,
                'step_stats': step_stats,
                'user_stats': list(user_stats),
                'recommendations': self._generate_template_recommendations(template, instances)
            }
            
        except Exception as e:
            logger.error(f"分析模板使用情况失败: {e}")
            raise
    
    def _analyze_template_steps(self, template: WorkflowTemplate, instances) -> Dict:
        """分析模板步骤统计"""
        
        workflow_def = template.workflow_definition
        steps = workflow_def.get('steps', [])
        
        step_stats = {}
        
        for step in steps:
            step_id = step.get('id')
            step_name = step.get('name', step_id)
            
            # 获取该步骤的所有任务
            step_tasks = WorkflowStepTask.objects.filter(
                workflow_instance__in=instances,
                step_id=step_id
            )
            
            total_tasks = step_tasks.count()
            if total_tasks > 0:
                completed_tasks = step_tasks.filter(status='completed').count()
                failed_tasks = step_tasks.filter(status='failed').count()
                pending_tasks = step_tasks.filter(status='pending').count()
                
                # 计算平均处理时间
                completed_with_time = step_tasks.filter(
                    status='completed',
                    started_at__isnull=False,
                    completed_at__isnull=False
                )
                
                avg_duration = None
                if completed_with_time.exists():
                    durations = [
                        (task.completed_at - task.started_at).total_seconds()
                        for task in completed_with_time
                    ]
                    avg_duration = sum(durations) / len(durations)
                
                step_stats[step_id] = {
                    'step_name': step_name,
                    'total_tasks': total_tasks,
                    'completed_tasks': completed_tasks,
                    'failed_tasks': failed_tasks,
                    'pending_tasks': pending_tasks,
                    'completion_rate': completed_tasks / total_tasks * 100,
                    'avg_duration': avg_duration
                }
        
        return step_stats
    
    def _generate_template_recommendations(self, template: WorkflowTemplate, instances) -> List[Dict]:
        """生成模板优化建议"""
        
        recommendations = []
        
        # 分析完成率
        total_instances = instances.count()
        completed_instances = instances.filter(status='completed').count()
        
        if total_instances > 0:
            completion_rate = completed_instances / total_instances * 100
            
            if completion_rate < 70:
                recommendations.append({
                    'type': 'low_completion_rate',
                    'priority': 'high',
                    'title': '完成率偏低',
                    'description': f'模板完成率仅为 {completion_rate:.1f}%，建议检查流程设计',
                    'suggestion': '检查是否存在不必要的步骤或过于复杂的审批流程'
                })
        
        # 分析处理时间
        completed_with_time = instances.filter(
            status='completed',
            started_at__isnull=False,
            completed_at__isnull=False
        )
        
        if completed_with_time.exists():
            durations = [
                (instance.completed_at - instance.started_at).total_seconds() / 3600
                for instance in completed_with_time
            ]
            avg_duration = sum(durations) / len(durations)
            
            if avg_duration > 72:  # 超过3天
                recommendations.append({
                    'type': 'long_processing_time',
                    'priority': 'medium',
                    'title': '处理时间过长',
                    'description': f'平均处理时间为 {avg_duration:.1f} 小时',
                    'suggestion': '考虑并行处理某些步骤或简化审批流程'
                })
        
        # 分析失败率
        failed_instances = instances.filter(status='failed').count()
        if total_instances > 0:
            failure_rate = failed_instances / total_instances * 100
            
            if failure_rate > 10:
                recommendations.append({
                    'type': 'high_failure_rate',
                    'priority': 'high',
                    'title': '失败率偏高',
                    'description': f'模板失败率为 {failure_rate:.1f}%',
                    'suggestion': '检查自动化步骤的配置和错误处理机制'
                })
        
        return recommendations
    
    def create_template_version(self, template_id: int, changes: Dict, created_by: User) -> WorkflowTemplate:
        """创建模板版本"""
        
        try:
            original_template = WorkflowTemplate.objects.get(id=template_id)
            
            # 创建新版本
            new_version = original_template.version + 1
            
            new_template = WorkflowTemplate.objects.create(
                name=original_template.name,
                template_type=original_template.template_type,
                description=original_template.description,
                workflow_definition=changes.get('workflow_definition', original_template.workflow_definition),
                created_by=created_by,
                version=new_version,
                parent_template_id=original_template.id
            )
            
            # 停用旧版本
            if changes.get('deactivate_old_version', False):
                original_template.is_active = False
                original_template.save()
            
            logger.info(f"创建模板版本: {original_template.id} -> {new_template.id} (v{new_version})")
            return new_template
            
        except Exception as e:
            logger.error(f"创建模板版本失败: {e}")
            raise
    
    def compare_template_versions(self, template_id1: int, template_id2: int) -> Dict:
        """比较模板版本差异"""
        
        try:
            template1 = WorkflowTemplate.objects.get(id=template_id1)
            template2 = WorkflowTemplate.objects.get(id=template_id2)
            
            def1 = template1.workflow_definition
            def2 = template2.workflow_definition
            
            differences = {
                'basic_info': {},
                'steps': {
                    'added': [],
                    'removed': [],
                    'modified': []
                },
                'summary': {}
            }
            
            # 比较基本信息
            if template1.name != template2.name:
                differences['basic_info']['name'] = {
                    'old': template1.name,
                    'new': template2.name
                }
            
            if template1.description != template2.description:
                differences['basic_info']['description'] = {
                    'old': template1.description,
                    'new': template2.description
                }
            
            # 比较步骤
            steps1 = {step['id']: step for step in def1.get('steps', [])}
            steps2 = {step['id']: step for step in def2.get('steps', [])}
            
            # 找出新增的步骤
            for step_id in steps2:
                if step_id not in steps1:
                    differences['steps']['added'].append(steps2[step_id])
            
            # 找出删除的步骤
            for step_id in steps1:
                if step_id not in steps2:
                    differences['steps']['removed'].append(steps1[step_id])
            
            # 找出修改的步骤
            for step_id in steps1:
                if step_id in steps2:
                    if steps1[step_id] != steps2[step_id]:
                        differences['steps']['modified'].append({
                            'step_id': step_id,
                            'old': steps1[step_id],
                            'new': steps2[step_id]
                        })
            
            # 生成摘要
            differences['summary'] = {
                'total_changes': (
                    len(differences['basic_info']) +
                    len(differences['steps']['added']) +
                    len(differences['steps']['removed']) +
                    len(differences['steps']['modified'])
                ),
                'steps_added': len(differences['steps']['added']),
                'steps_removed': len(differences['steps']['removed']),
                'steps_modified': len(differences['steps']['modified'])
            }
            
            return differences
            
        except Exception as e:
            logger.error(f"比较模板版本失败: {e}")
            raise


# 创建全局实例
template_manager = WorkflowTemplateManager()